package dao.impl;

import dao.UserDao;
import domain.User;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import utils.JDBCUtils;

import java.util.*;

/**
 * 数据库的操作类
 *
 * @author Mc.Chai
 * @program: JavaWeb
 * @create 2022-03-31-21:20 21:20
 */
public class UserDaoImpl implements UserDao {
    private JdbcTemplate jdbcTemplate=new JdbcTemplate(JDBCUtils.getDataSource());

    /**
     * 返回用户的信息
     * */
    @Override
    public List<User> findAll() {
        //使用JDBC操作数据库
        String sql="select * from user";
        //进行查询，其中包含利用工具类进行对象的封装
        List<User> users = jdbcTemplate.query(sql, new BeanPropertyRowMapper<User>(User.class));

        return users;
    }
    /**
     * 查询传入的username和password同时成立的user数据
     *
     * 异常：Incorrect result size: expected 1, actual 0 ;  预期1，实际0
     * @return 成功返回User对象，失败返回null
     * */
    @Override
    public User findUserByUsernameAndPassword(String username, String password) {

        User user = null;
        try {
            String sql="select * from User where username=? and password=?";
            //查询数据库中符合sql的用户对象（期待1条信息）
            user = jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<User>(User.class), username, password);
            return user;
        } catch (DataAccessException e) {
            //如果查不到发生异常
            return null;
        }


    }
    /**
     * 添加用户的数据
     * */
    @Override
    public void add(User user) {
        String sql="insert into user values (null,?,?,?,?,?,?,null,null)";
        jdbcTemplate.update(sql,user.getName(),user.getGender(),user.getAge(),user.getHomeTown(),user.getQq(),user.getEmail());
    }

    /**
     * 删除当前行用户的数据
     * @param id 被删除用户的id
     * */
    @Override
    public void delete(int id) {
        String sql="delete from user where id=?";
        jdbcTemplate.update(sql,id);
    }
    /**
     * 用户信息的回显，根据id查询用户所有的信息
     * */
    @Override
    public User findUserById(String id) {
        String sql="select * from user where id=?";
        User user = jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<User>(User.class), id);
        return user;
    }

    /**
     * 用户信息的修改
     * */
    @Override
    public void update(User user) {
        String sql="update user set name=?,gender=?,age=?,homeTown=?,qq=?,email=? where id=?";
        jdbcTemplate.update(sql,user.getName(),user.getGender(),user.getAge(),user.getHomeTown(),user.getQq(),user.getEmail(),user.getId());
    }
    /**
     * condition中数据例：  name:李  homeTown:北京
     * 在查询条件中，并不知道用户输入几个查询的条件，需要在sql语句中进行动态的添加
     * select * from user where 1 = 1  and name like ? limit ?,?
     * 使用模糊查询
     * 将start和rows添加到list集合中
     * */
    @Override
    public List<User> findByPage(int start, int rows, Map<String, String[]> condition) {
        //select * from user limit  开始的索引，每页查询的条数
        String sql="select * from user where 1 = 1 ";
        //调用抽取方法sqlAppend(sql,condition)
        Map<String, Object> map = sqlAppend(sql, condition);
        StringBuilder stringBuilder= (StringBuilder) map.get("sql");
        List list = (List) map.get("list");
        //select * from user where 1 = 1  and name like ? limit ?,?   注意语句的格式*/
        stringBuilder.append(" limit ?,?");
        list.add(start);
        list.add(rows);
        sql=stringBuilder.toString();
        System.out.println(sql);
        //query方法返回多结果集，queryForObject返回单结果集
        System.out.println(list);
        List<User> query = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(User.class),list.toArray());
        return query;
    }

    @Override
    public int findTotalCount(Map<String, String[]> condition) {
        String sql="select count(*) from user where 1=1 ";
        Map map = sqlAppend(sql, condition);
        sql = map.get("sql").toString();
        List list = (List) map.get("list");

        return jdbcTemplate.queryForObject(sql, Integer.class,list.toArray());
    }
    /**
     * 进行sql查询条件的拼接和拼接参数的整合
     * 返回一个map集合，通过list和sql参数分别获取list集合，和拼接的StringBuilder的sql
     * @return List,String
     * */
    public Map<String,Object> sqlAppend(String sql,Map<String, String[]> condition){
        Set<String> strings = condition.keySet();
        //进行sql字符串的拼接
        StringBuilder stringBuilder = new StringBuilder(sql);
        //利用list集合进行存储需要拼接的value数据
        List<Object> list = new ArrayList<>();
        for (String key : strings) {
            if ("currentPage".equals(key)||"rows".equals(key)){
                continue;
            }
            //获取key对应的键值，原为value数组，在查询中只定义一个value与之对应，所以简写为一个值
            String value = condition.get(key)[0];
            if (value!=null && !"".equals(value)){
                stringBuilder.append(" and "+key+" like ?");
                //将需要拼接的value数据放在list集合中，方便下面为?进行赋值
                list.add("%"+value+"%");
            }
        }
        HashMap<String, Object> hashMap = new HashMap<>();
        hashMap.put("sql",stringBuilder);
        hashMap.put("list",list);
        return hashMap;
    }
}
